/*根据需要自行添加所需头文件*/
#include "stdio.h"
#include "unistd.h"
#include "time.h"
#include "esp_log.h"
#include "user_include.h"

static const char* TAG = "aht20";


esp_err_t user_iic_init(void)
{
	i2c_config_t aht20_i2c_conf = {
	    .mode = I2C_MODE_MASTER,
	    .sda_io_num = AHT20_SDA_PIN, //default pin for SDA
	    .scl_io_num = AHT20_SCL_PIN, //default pin for SCL
	    .sda_pullup_en = GPIO_PULLUP_ENABLE,
	    .scl_pullup_en = GPIO_PULLUP_ENABLE,
	    .master.clk_speed = 100000
	};
	esp_err_t err = i2c_param_config(i2c_master_port, &aht20_i2c_conf);
	if (err != ESP_OK) {
	    return err;
	}
	return i2c_driver_install(i2c_master_port, aht20_i2c_conf.mode, 0, 0, 0);
}

esp_err_t __attribute__((unused)) i2c_master_read_slave(i2c_port_t i2c_num, uint8_t slave_addr, uint8_t *data_rd, size_t size)
{
    if (size == 0) {
        return ESP_OK;
    }
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_READ, ACK_CHECK_EN);
    if (size > 1) {
        i2c_master_read(cmd, data_rd, size - 1, ACK_VAL);
    }
    i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}

esp_err_t __attribute__((unused)) i2c_master_write_slave(i2c_port_t i2c_num, uint8_t slave_addr, uint8_t *data_wr, size_t size)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (slave_addr << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN);
    i2c_master_write(cmd, data_wr, size, ACK_CHECK_EN);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd);
    return ret;
}

uint8_t i2c_read_status()
{
	uint8_t buf[1];
	i2c_master_read_slave(i2c_master_port, aht20_addr, buf, sizeof(buf));
	return buf[0];
}

bool getbit(int NUM, int n){
    if(NUM &(1<<n)){return true;}
    else {return false;}
}

void check_calibration(){
    uint8_t status_byte[1] = {0};
    i2c_cmd_handle_t cmd_handle = i2c_cmd_link_create();
    i2c_master_start(cmd_handle); //0x71
    i2c_master_write_byte(cmd_handle, (aht20_addr << 1 | I2C_MASTER_READ), true ); //send 0x71
    i2c_master_read_byte(cmd_handle, (uint8_t *) &status_byte, I2C_MASTER_ACK);
    i2c_master_stop(cmd_handle);
    i2c_master_cmd_begin(I2C_NUM_0, cmd_handle, 1000 / portTICK_PERIOD_MS);
    i2c_cmd_link_delete(cmd_handle);
    if(!(getbit(status_byte[0],3))){
        i2c_cmd_handle_t cmd_handle = i2c_cmd_link_create();
        i2c_master_start(cmd_handle);
        i2c_master_write_byte(cmd_handle, (aht20_addr << 1 | I2C_MASTER_WRITE), true );
        i2c_master_write_byte(cmd_handle, (0xbe), true);
        i2c_master_write_byte(cmd_handle, (0x08), true);
        i2c_master_write_byte(cmd_handle, (0x00), true);
        i2c_master_stop(cmd_handle);
        i2c_master_cmd_begin(I2C_NUM_0, cmd_handle, 1000 / portTICK_PERIOD_MS);
        i2c_cmd_link_delete(cmd_handle);
    }
    printf("status %u\n", (uint8_t)status_byte[0]);
    vTaskDelay(100 / portTICK_PERIOD_MS);
}

void trigger_measure(){
	uint8_t buf[3] = {0xac,0x33,0x00};
	i2c_master_write_slave(i2c_master_port, aht20_addr, buf, sizeof(buf));
}

void getSensorData(uint8_t* data, temp_humi_t* aht20_data)
{
	i2c_master_read_slave(i2c_master_port, aht20_addr, data, 7);
    uint32_t rh = ( ((uint32_t)data[1] << 16) | ((uint32_t)data[2] << 8) | (data[3]) ) >> 4 ;
    uint32_t temp = ((uint32_t)(data[3]&0x0F) << 16) | ((uint32_t)data[4] << 8) | (uint32_t)data[5] ;
    aht20_data->temperature = (temp *(0.00019073F)-50);
    aht20_data->huminity = (rh * (0.0000953674316F));
}

void user_aht20_task(void *ignore){
	user_iic_init();
    vTaskDelay(200 / portTICK_PERIOD_MS);
    if((i2c_read_status()&0x18) != 0x18)
    {
    	//初始化0x1B,0x1C,0x1E寄存器
    	return;
    }
    uint8_t data[7];
    while(1){
    	trigger_measure();
    	vTaskDelay(100 / portTICK_PERIOD_MS);
    	getSensorData(data, &temp_humi_flag);
        // printf("Temperature is %3.2f  ", (float) temp_humi_flag.temperature);
        // printf("Humidity is %3.2f\n", (float) temp_humi_flag.huminity);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}
